Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add possible "first"/"second" to error-message (thanks, rmax!) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | bug-0439e1e1a3 |
Files: | files | file ages | folders |
SHA3-256: |
e2bcafbe4a0e0d475611e4da03e4d40e |
User & Date: | jan.nijtmans 2024-07-08 11:02:13.392 |
Context
2024-07-08
| ||
13:54 | first/second -> left/right and can't -> cannot check-in: ab1a9c2cf6 user: jan.nijtmans tags: bug-0439e1e1a3 | |
11:02 | Add possible "first"/"second" to error-message (thanks, rmax!) check-in: e2bcafbe4a user: jan.nijtmans tags: bug-0439e1e1a3 | |
09:15 | Additional testcases (not only testing for lseq, but for list and dict as well) check-in: e51bda5301 user: jan.nijtmans tags: bug-0439e1e1a3 | |
Changes
Changes to generic/tclExecute.c.
︙ | ︙ | |||
636 637 638 639 640 641 642 | static ExceptionRange * GetExceptRangeForPc(const unsigned char *pc, int searchMode, ByteCode *codePtr); static const char * GetSrcInfoForPc(const unsigned char *pc, ByteCode *codePtr, Tcl_Size *lengthPtr, const unsigned char **pcBeg, Tcl_Size *cmdIdxPtr); static Tcl_Obj ** GrowEvaluationStack(ExecEnv *eePtr, size_t growth, int move); | | | 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 | static ExceptionRange * GetExceptRangeForPc(const unsigned char *pc, int searchMode, ByteCode *codePtr); static const char * GetSrcInfoForPc(const unsigned char *pc, ByteCode *codePtr, Tcl_Size *lengthPtr, const unsigned char **pcBeg, Tcl_Size *cmdIdxPtr); static Tcl_Obj ** GrowEvaluationStack(ExecEnv *eePtr, size_t growth, int move); static void IllegalExprOperandType(Tcl_Interp *interp, const char *ord, const unsigned char *pc, Tcl_Obj *opndPtr); static void InitByteCodeExecution(Tcl_Interp *interp); static inline int wordSkip(void *ptr); static void ReleaseDictIterator(Tcl_Obj *objPtr); /* Useful elsewhere, make available in tclInt.h or stubs? */ static Tcl_Obj ** StackAllocWords(Tcl_Interp *interp, size_t numWords); static Tcl_Obj ** StackReallocWords(Tcl_Interp *interp, size_t numWords); |
︙ | ︙ | |||
5870 5871 5872 5873 5874 5875 5876 | if ((GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK) || (type1==TCL_NUMBER_DOUBLE) || (type1==TCL_NUMBER_NAN)) { TRACE(("%.20s %.20s => ILLEGAL 1st TYPE %s\n", O2S(valuePtr), O2S(value2Ptr), (valuePtr->typePtr? valuePtr->typePtr->name : "null"))); DECACHE_STACK_INFO(); | | | | 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 | if ((GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK) || (type1==TCL_NUMBER_DOUBLE) || (type1==TCL_NUMBER_NAN)) { TRACE(("%.20s %.20s => ILLEGAL 1st TYPE %s\n", O2S(valuePtr), O2S(value2Ptr), (valuePtr->typePtr? valuePtr->typePtr->name : "null"))); DECACHE_STACK_INFO(); IllegalExprOperandType(interp, "first ", pc, valuePtr); CACHE_STACK_INFO(); goto gotError; } if ((GetNumberFromObj(NULL, value2Ptr, &ptr2, &type2) != TCL_OK) || (type2==TCL_NUMBER_DOUBLE) || (type2==TCL_NUMBER_NAN)) { TRACE(("%.20s %.20s => ILLEGAL 2nd TYPE %s\n", O2S(valuePtr), O2S(value2Ptr), (value2Ptr->typePtr? value2Ptr->typePtr->name : "null"))); DECACHE_STACK_INFO(); IllegalExprOperandType(interp, "second ", pc, value2Ptr); CACHE_STACK_INFO(); goto gotError; } /* * Check for common, simple case. */ |
︙ | ︙ | |||
6091 6092 6093 6094 6095 6096 6097 | if ((GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK) || IsErroringNaNType(type1)) { TRACE(("%.20s %.20s => ILLEGAL 1st TYPE %s\n", O2S(value2Ptr), O2S(valuePtr), (valuePtr->typePtr? valuePtr->typePtr->name: "null"))); DECACHE_STACK_INFO(); | | | | 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 | if ((GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK) || IsErroringNaNType(type1)) { TRACE(("%.20s %.20s => ILLEGAL 1st TYPE %s\n", O2S(value2Ptr), O2S(valuePtr), (valuePtr->typePtr? valuePtr->typePtr->name: "null"))); DECACHE_STACK_INFO(); IllegalExprOperandType(interp, "first ", pc, valuePtr); CACHE_STACK_INFO(); goto gotError; } #ifdef ACCEPT_NAN if (type1 == TCL_NUMBER_NAN) { /* * NaN first argument -> result is also NaN. */ NEXT_INST_F(1, 1, 0); } #endif if ((GetNumberFromObj(NULL, value2Ptr, &ptr2, &type2) != TCL_OK) || IsErroringNaNType(type2)) { TRACE(("%.20s %.20s => ILLEGAL 2nd TYPE %s\n", O2S(value2Ptr), O2S(valuePtr), (value2Ptr->typePtr? value2Ptr->typePtr->name: "null"))); DECACHE_STACK_INFO(); IllegalExprOperandType(interp, "second ", pc, value2Ptr); CACHE_STACK_INFO(); goto gotError; } #ifdef ACCEPT_NAN if (type2 == TCL_NUMBER_NAN) { /* |
︙ | ︙ | |||
6254 6255 6256 6257 6258 6259 6260 | /* TODO - check claim that taking address of b harms performance */ /* TODO - consider optimization search for constants */ if (TclGetBooleanFromObj(NULL, valuePtr, &b) != TCL_OK) { TRACE(("\"%.20s\" => ERROR: illegal type %s\n", O2S(valuePtr), (valuePtr->typePtr? valuePtr->typePtr->name : "null"))); DECACHE_STACK_INFO(); | | | 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 | /* TODO - check claim that taking address of b harms performance */ /* TODO - consider optimization search for constants */ if (TclGetBooleanFromObj(NULL, valuePtr, &b) != TCL_OK) { TRACE(("\"%.20s\" => ERROR: illegal type %s\n", O2S(valuePtr), (valuePtr->typePtr? valuePtr->typePtr->name : "null"))); DECACHE_STACK_INFO(); IllegalExprOperandType(interp, "", pc, valuePtr); CACHE_STACK_INFO(); goto gotError; } /* TODO: Consider peephole opt. */ objResultPtr = TCONST(!b); TRACE_WITH_OBJ(("%s => ", O2S(valuePtr)), objResultPtr); NEXT_INST_F(1, 1, 1); |
︙ | ︙ | |||
6276 6277 6278 6279 6280 6281 6282 | /* * ... ~$NonInteger => raise an error. */ TRACE_APPEND(("ERROR: illegal type %s\n", (valuePtr->typePtr? valuePtr->typePtr->name : "null"))); DECACHE_STACK_INFO(); | | | 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 | /* * ... ~$NonInteger => raise an error. */ TRACE_APPEND(("ERROR: illegal type %s\n", (valuePtr->typePtr? valuePtr->typePtr->name : "null"))); DECACHE_STACK_INFO(); IllegalExprOperandType(interp, "", pc, valuePtr); CACHE_STACK_INFO(); goto gotError; } if (type1 == TCL_NUMBER_INT) { w1 = *((const Tcl_WideInt *) ptr1); if (Tcl_IsShared(valuePtr)) { TclNewIntObj(objResultPtr, ~w1); |
︙ | ︙ | |||
6308 6309 6310 6311 6312 6313 6314 | valuePtr = OBJ_AT_TOS; TRACE(("\"%.20s\" => ", O2S(valuePtr))); if ((GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK) || IsErroringNaNType(type1)) { TRACE_APPEND(("ERROR: illegal type %s \n", (valuePtr->typePtr? valuePtr->typePtr->name : "null"))); DECACHE_STACK_INFO(); | | | 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 | valuePtr = OBJ_AT_TOS; TRACE(("\"%.20s\" => ", O2S(valuePtr))); if ((GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK) || IsErroringNaNType(type1)) { TRACE_APPEND(("ERROR: illegal type %s \n", (valuePtr->typePtr? valuePtr->typePtr->name : "null"))); DECACHE_STACK_INFO(); IllegalExprOperandType(interp, "", pc, valuePtr); CACHE_STACK_INFO(); goto gotError; } switch (type1) { case TCL_NUMBER_NAN: /* -NaN => NaN */ TRACE_APPEND(("%s\n", O2S(valuePtr))); |
︙ | ︙ | |||
6361 6362 6363 6364 6365 6366 6367 | /* * ... +$NonNumeric => raise an error. */ TRACE_APPEND(("ERROR: illegal type %s\n", (valuePtr->typePtr? valuePtr->typePtr->name:"null"))); DECACHE_STACK_INFO(); | | | | 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 | /* * ... +$NonNumeric => raise an error. */ TRACE_APPEND(("ERROR: illegal type %s\n", (valuePtr->typePtr? valuePtr->typePtr->name:"null"))); DECACHE_STACK_INFO(); IllegalExprOperandType(interp, "", pc, valuePtr); CACHE_STACK_INFO(); goto gotError; } /* ... TryConvertToNumeric($NonNumeric) is acceptable */ TRACE_APPEND(("not numeric\n")); NEXT_INST_F(1, 0, 0); } if (IsErroringNaNType(type1)) { if (*pc == INST_UPLUS) { /* * ... +$NonNumeric => raise an error. */ TRACE_APPEND(("ERROR: illegal type %s\n", (valuePtr->typePtr? valuePtr->typePtr->name:"null"))); DECACHE_STACK_INFO(); IllegalExprOperandType(interp, "", pc, valuePtr); CACHE_STACK_INFO(); } else { /* * Numeric conversion of NaN -> error. */ TRACE_APPEND(("ERROR: IEEE floating pt error\n")); |
︙ | ︙ | |||
9100 9101 9102 9103 9104 9105 9106 9107 9108 9109 9110 9111 9112 9113 | *---------------------------------------------------------------------- */ static void IllegalExprOperandType( Tcl_Interp *interp, /* Interpreter to which error information * pertains. */ const unsigned char *pc, /* Points to the instruction being executed * when the illegal type was found. */ Tcl_Obj *opndPtr) /* Points to the operand holding the value * with the illegal type. */ { void *ptr; int type; | > | 9100 9101 9102 9103 9104 9105 9106 9107 9108 9109 9110 9111 9112 9113 9114 | *---------------------------------------------------------------------- */ static void IllegalExprOperandType( Tcl_Interp *interp, /* Interpreter to which error information * pertains. */ const char *ord, /* "first ", "second " or "" */ const unsigned char *pc, /* Points to the instruction being executed * when the illegal type was found. */ Tcl_Obj *opndPtr) /* Points to the operand holding the value * with the illegal type. */ { void *ptr; int type; |
︙ | ︙ | |||
9123 9124 9125 9126 9127 9128 9129 | if (GetNumberFromObj(NULL, opndPtr, &ptr, &type) != TCL_OK) { Tcl_Size length; if (TclHasInternalRep(opndPtr, &tclDictType)) { Tcl_DictObjSize(NULL, opndPtr, &length); if (length > 1) { listRep: Tcl_SetObjResult(interp, Tcl_ObjPrintf( | | | 9124 9125 9126 9127 9128 9129 9130 9131 9132 9133 9134 9135 9136 9137 9138 | if (GetNumberFromObj(NULL, opndPtr, &ptr, &type) != TCL_OK) { Tcl_Size length; if (TclHasInternalRep(opndPtr, &tclDictType)) { Tcl_DictObjSize(NULL, opndPtr, &length); if (length > 1) { listRep: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't use a list as %soperand of \"%s\"", ord, op)); Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", "list", (char *)NULL); return; } } Tcl_ObjTypeLengthProc *lengthProc = TclObjTypeHasProc(opndPtr, lengthProc); if (lengthProc && lengthProc(opndPtr) > 1) { goto listRep; |
︙ | ︙ |
Changes to tests/expr.test.
︙ | ︙ | |||
499 500 501 502 503 504 505 | list [catch {expr {2.3/0.0}} msg] $msg } {1 {divide by zero}} test expr-11.13b {CompileAddExpr: runtime error} ieeeFloatingPoint { list [catch {expr {2.3/0.0}} msg] $msg } {0 Inf} test expr-11.14 {CompileAddExpr: runtime error} { list [catch {expr {24.0+[lseq 2 4]}} msg] $msg | | | | | | | 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 | list [catch {expr {2.3/0.0}} msg] $msg } {1 {divide by zero}} test expr-11.13b {CompileAddExpr: runtime error} ieeeFloatingPoint { list [catch {expr {2.3/0.0}} msg] $msg } {0 Inf} test expr-11.14 {CompileAddExpr: runtime error} { list [catch {expr {24.0+[lseq 2 4]}} msg] $msg } {1 {can't use a list as second operand of "+"}} test expr-11.15 {CompileAddExpr: runtime error} { list [catch {expr {{1 2 3}+24.0}} msg] $msg } {1 {can't use a list as first operand of "+"}} test expr-11.16 {CompileAddExpr: runtime error} { list [catch {expr {~[dict create foo bar]}} msg] $msg } {1 {can't use a list as operand of "~"}} test expr-12.1 {CompileMultiplyExpr: just unary expr} {expr ~4} -5 test expr-12.2 {CompileMultiplyExpr: just unary expr} {expr --5} 5 test expr-12.3 {CompileMultiplyExpr: just unary expr} {expr !27} 0 test expr-12.4 {CompileMultiplyExpr: just unary expr} {expr ~0xff00ff} -16711936 test expr-12.5 {CompileMultiplyExpr: error in unary expr} -body { expr ~x |
︙ | ︙ |